Skip to content

Conversation

@qucol-odoo
Copy link

No description provided.

@robodoo
Copy link

robodoo commented Oct 20, 2025

Pull request status dashboard

@Mathilde411 Mathilde411 changed the title Chapter 2 QUCOL Onboarding Oct 20, 2025
@Mathilde411 Mathilde411 requested a review from alan-odoo October 20, 2025 11:44
@qucol-odoo qucol-odoo force-pushed the 19.0-onboarding-qucol branch from 46fe336 to 5cda5fe Compare October 20, 2025 14:02
@qucol-odoo qucol-odoo force-pushed the 19.0-onboarding-qucol branch 2 times, most recently from ad8ec7f to 3a01b0f Compare October 20, 2025 14:12
@qucol-odoo qucol-odoo force-pushed the 19.0-onboarding-qucol branch 4 times, most recently from d0a617c to 0cf2ff3 Compare October 22, 2025 14:59
@qucol-odoo qucol-odoo closed this Oct 22, 2025
@qucol-odoo qucol-odoo reopened this Oct 22, 2025
@qucol-odoo qucol-odoo force-pushed the 19.0-onboarding-qucol branch 5 times, most recently from eff89b1 to 2faaaee Compare October 24, 2025 11:06
Copy link

@alan-odoo alan-odoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @qucol-odoo 👋,

Here is a review of your code. You went through the tutorials without much difficulty so I've been a little bit more touchy on your PR 😃.

Your branch is very clean! And we're not going to dirty it. Then can you do the corrections in the right commits ? In the end, your branch shouldn't contain new commit. If you meet some issue doing it, ping me 😃.

Thanks for your job and for helping your teammates!

Comment on lines 1 to 4
from . import estate_properties
from . import estate_property_types
from . import estate_property_tags
from . import estate_property_offers

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They should be listed alphabetically.

Comment on lines 5 to 7
DEFAULT_GARDEN_AREA = 10
DEFAULT_GARDEN_ORIENTATION = "north"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's the right way to write constants but I am not sure to understand why it is required. They are used only in _update_garden_area_and_orientation, can they be defined directly in that method?

selection=[('north', 'North'), ('south', 'South'), ('east', 'East'), ('west', 'West')]
)
total_living_area = fields.Integer(compute="_compute_total_area")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need of that blank line 😃.

record.total_living_area = record.living_area + record.garden_area

@api.depends("offer_ids")
def _get_highest_price(self):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this method is used to compute the best_price, it should be named _compute_best_offer 😃, that way we know easily 1. it computes field and 2 which field.

FYI, _get or get methods should return an object and should not modify the database. For example, _get_res_user should only return a res_user and do nothing else.

record.best_offer = max(record.offer_ids.mapped("price")) if record.offer_ids else 0

@api.onchange("garden")
def _update_garden_area_and_orientation(self):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

<field name="arch" type="xml">
<form string="Property type">
<sheet>
<button name="%(estate.estate_property_offer_action)d" string="Offers" type="action" title="Offers list" invisible="not offer_count > 0"/>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<button name="%(estate.estate_property_offer_action)d" string="Offers" type="action" title="Offers list" invisible="not offer_count > 0"/>
<button name="%(estate.estate_property_offer_action)d" string="Offers" type="action" title="Offers list" invisible="offer_count == 0"/>

<field name="name"/>
</h1>
<group>
<field name="offer_count"/>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you can test to add it inside your oe_stat_button ? (not a priority). You can find a solution here (line 847)

@@ -0,0 +1,21 @@
<odoo>
<record id="estate_res_user_view_form" model="ir.ui.view">

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can call it as its parent. Other modules will refer to this one as estate.res_user_view_form. So here we know that the main form of the user has been modified and this is not a new one.

Suggested change
<record id="estate_res_user_view_form" model="ir.ui.view">
<record id="res_user_view_form" model="ir.ui.view">

],
'data': [
'security/ir.model.access.csv',

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need of this blank line. Do not forget that a lot of developers are working on the project and we must avoid unnecessary changes.

Comment on lines 36 to 43
taken_ids = set()
for invoice in self.env["account.move"].search([]):
if (match := re.match(r"Invoice\s+(\d+)", invoice.name)):
taken_ids.add(int(match.group(1)))
i = 1
while i in taken_ids:
i += 1
return f"Invoice {i}"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to select the first number missing in the sequence or the one above the maximum ?
If it is the last case, I would do something like that to avoid too many loops.

Suggested change
taken_ids = set()
for invoice in self.env["account.move"].search([]):
if (match := re.match(r"Invoice\s+(\d+)", invoice.name)):
taken_ids.add(int(match.group(1)))
i = 1
while i in taken_ids:
i += 1
return f"Invoice {i}"
invoice = self.env["account.move"].search([("name", "like", "Invoice %")], order='id desc', limit=1)
if invoice and (match := re.match(r"Invoice (\d+)", invoice.name)):
return f"Invoice {match.group(1)}"
return "Invoice 1"

@qucol-odoo qucol-odoo force-pushed the 19.0-onboarding-qucol branch 3 times, most recently from 327b3f5 to 2a0540b Compare October 30, 2025 09:51
@qucol-odoo qucol-odoo force-pushed the 19.0-onboarding-qucol branch 2 times, most recently from 2eeb5b3 to 7784a59 Compare October 30, 2025 15:39
@qucol-odoo qucol-odoo force-pushed the 19.0-onboarding-qucol branch from 7784a59 to 3e9e034 Compare October 30, 2025 15:56
Copy link

@alan-odoo alan-odoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @qucol-odoo 😃,

Just a quick review. Those changes are not a priority as we are arriving at the end of the onboarding. It's just to let you know about other good practices.

About the title of your PR, its pattern is the same as the one of the commits. [IMP/FIX/ADD/...]: applications: what the PR is doing (starting with a verb). Here for the applications you could write estate{_account}. We use {} to avoid estate, estate_account. We squash them. And if there are to much app, you just write * in the title and in the description you write * = all the names of the apps.
And for the description you should summarize the content of your commits. The description must mainly explain why you are doing your modifications and not how you reached the goal.
Once again no need to change it now, it's just for you to know.

Cheers !

Comment on lines 57 to 69
def create_sold_property(cls):
cls.sold_property = cls.env["estate.property"].create([{
"name": "Sold Property",
"state": "new",
"expected_price": 4000.0
}])
cls.env["estate.property.offer"].create([{
"partner_id": ADMINISTRATOR_ID,
"property_id": cls.sold_property.id,
"status": "accepted",
"price": 4000.0
}])
cls.sold_property.state = "sold"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should create functions/methods only if they are used several times or overridden. I must say that before Odoo I liked creating functions because according to me, it made the code more readable. But they asked me to stop 😅 because it creates a ping pong effect and you should be able to read as much code as possible at once.

from odoo.tests import tagged, Form


ADMINISTRATOR_ID = 3

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Data created in xml/csv have an external_id. This is the id of the xml record. It can be easily found. For example here you can search `model="res.partner"' in all your xml files and then you can check the demo data.

When you need to cache a record by its id you can used the ref method of self.env. It contacts the ir_model_data table which contains all the external ids and with the other information of the record in that table its able to find where is the record asked.

Also we usually do not write global constants. So you could just put it inside the setUpClass.

Suggested change
ADMINISTRATOR_ID = 3
ADMINISTRATOR_ID = self.env.ref("base.partner_admin").id

Comment on lines 84 to 88
for offer in correct_offers:
try:
self.env["estate.property.offer"].create([offer])
except UserError:
self.fail()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to catch the exception 😃, or maybe I'm missing something. If an exception occurs the test doesn't pass. As it can make a code a bit less readable, do not hesitate to write why you do that. Do not forget always why and not how as every developer should be able to read your code, but sometimes the purpose may not be clear.

<field name="postcode"/>
<field name="expected_price"/>
<field name="bedrooms"/>
<field name="living_area" filter_domain="['|', ('living_area', '=', self), ('living_area', '&gt;', self)]"/>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you do this?

Suggested change
<field name="living_area" filter_domain="['|', ('living_area', '=', self), ('living_area', '&gt;', self)]"/>
<field name="living_area" filter_domain="[('living_area', '&gt;=', self)]"/>

@qucol-odoo qucol-odoo force-pushed the 19.0-onboarding-qucol branch from 3e9e034 to 601b9a6 Compare October 31, 2025 13:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants